package cn.itsub.proxy.server.app.controller;


import cn.itsub.proxy.common.Config;
import cn.itsub.proxy.common.utils.Result;
import cn.itsub.proxy.server.app.entity.Client;
import cn.itsub.proxy.server.app.entity.Tunnel;
import cn.itsub.proxy.server.app.mapper.ClientMapper;
import cn.itsub.proxy.server.app.mapper.TunnelMapper;
import cn.itsub.proxy.server.work.ProxyChannelManager;
import cn.itsub.proxy.server.work.config.ProxyConfig;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.gson.JsonArray;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.UUID;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Java夏老师
 * @since 2021-09-20
 */
@Controller
public class MainController {

    Config config = Config.getInstance();
    @Autowired
    ClientMapper clientMapper;
    @Autowired
    TunnelMapper tunnelMapper;

    @GetMapping(value = {"/index.html","/","/index"})
    public String index_html() {
        return "index";
    }

    @GetMapping(value = {"/client"})
    public String client_html(Model model) {
        List<Client> clients = clientMapper.selectAll();
        model.addAttribute("clients", clients);
        return "client";
    }

    @GetMapping(value = {"/client-config"})
    public String tunnel_html(String clientKey, Model model) {
        Client client = clientMapper.selectByClientKey(clientKey);
        List<Tunnel> tunnelList = tunnelMapper.selectByClientKey(clientKey);


        model.addAttribute("client", client);
        model.addAttribute("tunnelList", tunnelList);
        return "client-config";
    }


    @GetMapping(value = {"/login.html"})
    public String login_html() {
        return "login";
    }

    @ResponseBody
    @PostMapping("/login.do")
    public Object login_do(String username, String password, HttpSession session) {
        String user = config.getStringValue("natoo.admin.username","admin");
        String b = config.getStringValue("natoo.admin.password","admin");
        if (!user.equals(username) || !b.equals(password)) {
            return Result.of(1,"用户名或密码不正确");
        }
        session.setAttribute("login",user);
        return Result.of(0,"登录成功");
    }

    @RequestMapping("/logout")
    public Object logout(HttpSession session) {
        session.invalidate();
        return "redirect:/login.html";
    }


    //获取所有映射
    @ResponseBody
    @RequestMapping("/mappings")
    public Object mappings() {
        JsonArray arr = ProxyConfig.getInstance().getMappings(null);
        return arr.toString();
    }

    @ResponseBody
    @RequestMapping("/api/client/list")
    public Object api_client_list() {
        List<Client> clients = clientMapper.selectAll();
        for (var cli : clients) {
            cli.online=ProxyChannelManager.isClientOnline(cli.clientKey);
        }
        return Result.of(200, "success").put("clients",clients);
    }

    @ResponseBody
    @RequestMapping("/api/client/create")
    public Object api_client_create(String name) {
        Client client = new Client();
        client.setName(name);
        client.setClientKey(UUID.randomUUID().toString().replaceAll("-",""));
        clientMapper.insert(client);
        return Result.of(200, "创建成功").put("data",client);
    }

    @ResponseBody
    @RequestMapping("/api/client/update")
    public Object api_client_update(Client client) {
        UpdateWrapper<Client> wp = new UpdateWrapper<>();
        wp.eq("id", client.id);
        wp.set("name", client.name);
        clientMapper.update(null, wp);
        return Result.of(200, "修改成功");
    }

    @ResponseBody
    @RequestMapping("/api/client/delete")
    public Object api_client_delete(int id) {
        List<Tunnel> list = tunnelMapper.selectByClientId(id);
        if (!list.isEmpty()) {
            return Result.of(400, "此终端包含映射，无法删除");
        }
        clientMapper.deleteById(id);
        return Result.of(200, "删除成功");
    }


    @ResponseBody
    @RequestMapping("/api/tunnel/list")
    public Object api_tunnel_list(String clientKey) {
        var list = tunnelMapper.selectByClientKey(clientKey);
        return Result.of(200, "success").put("data",list);
    }

    @ResponseBody
    @RequestMapping("/api/tunnel/create")
    public Object api_tunnel_create(Tunnel tunnel) {
        //clientKey,wanPort,lanHost,lanPort,name,remark
        tunnel.setState(0);
        if (tunnelMapper.selectByWanPort(tunnel.getWanPort()) != null) {
            return Result.of(400, "创建失败，外网端口已被占用");
        }
        if (clientMapper.selectByClientKey(tunnel.getClientKey()) == null) {
            return Result.of(400, "ClientKey不存在");
        }
        tunnelMapper.insert(tunnel);
        natooReloadTunnels(tunnel.getClientKey());
        return Result.of(200, "创建成功").put("data",tunnel);
    }

    @ResponseBody
    @RequestMapping("/api/tunnel/update")
    public Object api_tunnel_update(Tunnel fo) {
        //参数：id,wanPort,name,lanHost,lanPort,state,clientKey
        // id,wanPort,clientKey 禁止修改
        Tunnel tunnel = tunnelMapper.selectById(fo.getId());
        tunnel.setLanHost(fo.getLanHost());
        tunnel.setLanPort(fo.getLanPort());
        tunnel.setName(fo.getName());
        tunnel.setState(fo.getState());
        tunnelMapper.updateById(tunnel);
        natooReloadTunnels(tunnel.getClientKey());
        return Result.of(200, "创建成功").put("data",tunnel);
    }

    @ResponseBody
    @RequestMapping("/api/tunnel/turn")
    public Object api_tunnel_turn(int id,int state) {
        //clientKey,wanPort,lanHost,lanPort,name,remark
        Tunnel tunnel = tunnelMapper.selectById(id);
        if (tunnel == null) {
            return Result.of(400, "ID不存在");
        }
        UpdateWrapper<Tunnel> wp = new UpdateWrapper<>();
        wp.set("state", state);
        wp.eq("id", id);
        tunnelMapper.update(null, wp);

        natooReloadTunnels(tunnel.getClientKey());

        return Result.of(200, "修改成功").put("state",state);
    }

    @ResponseBody
    @RequestMapping("/api/tunnel/delete")
    public Object api_tunnel_delete(int id) {
        Tunnel tunnel = tunnelMapper.selectById(id);
        natooReloadTunnels(tunnel.getClientKey());
        tunnelMapper.deleteById(id);
        return Result.of(200, "删除成功");
    }


    private void natooReloadTunnels(String clientKey) {
        List<Tunnel> list = tunnelMapper.selectByClientKey(clientKey);
        ProxyConfig.getInstance().setClientTunnels(clientKey,list);
    }

}

